package gintool

import (
	"bytes"
	"github.com/gin-gonic/gin"
	"github.com/simplechain-org/client/log"
	"io/ioutil"
	"strings"
	"time"
)

// CustomResponseWriter 封装 gin ResponseWriter 用于获取回包内容。
type CustomResponseWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w CustomResponseWriter) Write(b []byte) (int, error) {
	w.body.Write(b)
	return w.ResponseWriter.Write(b)
}

// 日志中间件,记录调用信息和统计每天的调用次数
func Logger(interfaceStatistics InterfaceStatistics) gin.HandlerFunc {
	return func(c *gin.Context) {
		// 记录请求时间
		start := time.Now()

		// 使用自定义 ResponseWriter
		crw := &CustomResponseWriter{
			body:           bytes.NewBufferString(""),
			ResponseWriter: c.Writer,
		}
		c.Writer = crw

		// 打印请求信息
		reqBody, _ := c.GetRawData()
		c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))
		log.Info("[Gin-INFO-Request]",
			"reqMethod", c.Request.Method,
			"reqURI", c.Request.RequestURI,
			"reqBody", string(reqBody))

		// 执行请求处理程序和其他中间件函数
		c.Next()

		// 记录回包内容和处理时间
		end := time.Now()
		latency := end.Sub(start)
		respBody := string(crw.body.Bytes())
		urlPath := c.Request.URL.Path
		//针对restful接口特殊处理：目前只有v1/chain/validate/***和v1/chain/transaction/***接口
		if strings.Contains(urlPath, "v1/chain/validate") {
			urlPath = "v1/chain/validate"
		} else if strings.Contains(urlPath, "v1/chain/transaction") {
			urlPath = "v1/chain/transaction"
		}

		log.Info("[Gin-INFO-Response]",
			"reqMethod", c.Request.Method,
			"reqURI", c.Request.RequestURI,
			"reqPath", urlPath,
			"reqBody", string(reqBody),
			"respBody", respBody,
			"latency", latency)

		//更新统计信息
		interfaceStatistics.FnCallCountUpdate(start.Format("20060102"), urlPath)
	}
}

type InterfaceStatistics interface {
	FnCallCountUpdate(date, fnName string)
}
